home *** CD-ROM | disk | FTP | other *** search
- /*----------------------------------------------------------------------------
- libopt
- ------------------------------------------------------------------------------
- This is a program to convert link library filepaths to linker options
- that select them. E.g. ../pbm/libpbm.so becomes -L../pbm -lpbm .
-
- Each argument is a library filepath. The option string to identify
- all of those library filepaths goes to Standard Output.
-
- If an argument doesn't make sense as a library filespec, it is
- copied verbatim, blank delimited, to the output string.
-
- There is no newline or null character or anything after the output.
- ------------------------------------------------------------------------------
- Why would you want to use this?
-
- On some systems, the -L/-l output of this program has exactly the
- same effect as the filepath input when used in the arguments to a
- link command. A GNU/Linux system, for example. On others (Solaris,
- for example), if you include /tmp/lib/libpbm.so in the link as a
- link object, the executable gets built in such a way that the system
- accesses the shared library /tmp/lib/libpbm.so at run time. On the
- other hand, if you instead put the options -L/tmp/lib -lpbm on the
- link command, the executable gets built so that the system accesses
- libpbm.so in its actual installed directory at runtime (that
- location might be determined by a --rpath linker option or a
- LD_LIBRARY_PATH environment variable at run time).
-
- In a make file, it is nice to use the same variable as the
- dependency of rule that builds an executable and as the thing that
- the rule's command uses to identify its input. Here is an example
- of using libopt for that:
-
- PBMLIB=../pbm/libpbm.so
- ...
- pbmmake: pbmmake.o $(PBMLIB)
- ld -o pbmmake pbmmake.o `libopt $(PBMLIB)` --rpath=/lib/netpbm
-
- Caveat: "-L../pbm -lpbm" is NOT exactly the same as "libpbm.so" on any
- system. All of the -l libraries are searched for in all of the -L
- directories. So you just might get a different library with the -L/-l
- version than if you specify the library file explicitly.
-
- -----------------------------------------------------------------------------*/
- #define _BSD_SOURCE 1
- /* Make sure strdup() is in stdio.h */
-
- #include <string.h>
- #include <stdlib.h>
- #include <stdio.h>
-
- typedef unsigned char bool;
- #define true (1)
- #define false (0)
-
- static void
- parse_filename(const char * const filename,
- char ** const libname_p,
- bool * const valid_library_p) {
- /*----------------------------------------------------------------------------
- Extract the library name component of the filename 'filename'. This
- is just a filename, not a whole pathname.
-
- Return it in newly malloc'ed storage pointed to by '*libname_p'.
-
- E.g. for "libxyz.so", return "xyz".
-
- return *valid_library == true iff 'filename' validly names a library
- that can be expressed in a -l linker option.
- -----------------------------------------------------------------------------*/
- char *lastdot;
- /* Pointer to last period in 'filename'. Null if none */
-
- /* We accept any period-delimited suffix as a library type suffix.
- It's probably .so or .a, but is could be .kalamazoo for all we
- care.
- */
- lastdot = strrchr(filename, '.');
- if (lastdot == NULL) {
- /* This filename doesn't have any suffix, so we don't understand
- it as a library filename.
- */
- *valid_library_p = false;
- } else {
- if (strncmp(filename, "lib", 3) != 0) {
- /* This filename doesn't start with "lib", so we can't express
- it as a -l option.
- */
- *valid_library_p = false;
- } else {
- /* Extract everything between "lib" and "." as
- the library name
- */
- *libname_p = strdup(filename+3);
- (*libname_p)[lastdot - filename - 3] = '\0';
-
- if (strlen(*libname_p) == 0)
- *valid_library_p = false;
- else
- *valid_library_p = true;
- }
- }
- }
-
-
-
- static void
- parse_filepath(const char * const filepath,
- char ** const directory_p, char ** const filename_p) {
- /*----------------------------------------------------------------------------
- Extract the directory and filename components of the filepath
- 'filepath' and return them in newly malloc'ed storage pointed to by
- '*directory_p' and '*filename_p'.
- -----------------------------------------------------------------------------*/
- char *lastslash; /* Pointer to last slash in 'filepath', or null if none */
-
- lastslash = strrchr(filepath, '/');
-
- if (lastslash == NULL) {
- /* There's no directory component; the filename starts at the
- beginning of the filepath
- */
- *filename_p = strdup(filepath);
- *directory_p = strdup("");
- } else {
- /* Split the string at the slash we just found, into filename and
- directory
- */
- *filename_p = strdup(lastslash+1);
- *directory_p = strdup(filepath);
- (*directory_p)[lastslash - filepath] = '\0';
- }
- }
-
-
-
- int
- main(int argc, char **argv) {
-
- unsigned int arg; /* Index into argv[] of argument we're processing */
-
- for (arg = 1; arg < argc; arg++) {
- const char *filepath; /* The argument we're processing */
- bool valid_library;
- /* Our argument is a valid library filepath that can be converted to
- -l/-L notation.
- */
- char *directory;
- /* Directory component of 'filepath' */
- char *filename;
- /* Filename component of 'filepath' */
- char *libname;
- /* Library name component of 'filename'. e.g. xyz in libxyz.so */
-
- filepath = argv[arg];
-
- parse_filepath(filepath, &directory, &filename);
-
- parse_filename(filename, &libname, &valid_library);
-
- if (valid_library) {
- if (strlen(directory) == 0)
- fprintf(stdout, "-L. -l%s ", libname);
- else
- fprintf(stdout, "-L%s -l%s ", directory, libname);
- } else
- fprintf(stdout, "%s ", filepath);
-
- free(directory); free(filename); free(libname);
- }
- return 0;
- }
-
-
-
-
-
-